home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
machserver
/
1.098
/
dev
/
devExabyteTape.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-11
|
12KB
|
328 lines
/*
* devExabyteTape.c --
*
* Procedures that set up command blocks and process sense
* data for Exabyte tape drives.
* Definitions for sense data format and status information returned
* from Exabyte tape drives. Reference, the "EXB-8200 8mm Tape Drive
* User's Guide" by Perfect Byte, Inc. 7121 Cass St. Omaha, NE 68132
*
* Copyright 1989 Regents of the University of California
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies. The University of California
* makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without
* express or implied warranty.
*/
#ifndef lint
static char rcsid[] = "$Header: /sprite/src/kernel/dev/RCS/devExabyteTape.c,v 9.4 91/06/06 11:19:45 mendel Exp $ SPRITE (Berkeley)";
#endif not lint
#include "sprite.h"
#include "stdio.h"
#include "dev.h"
#include "scsi.h"
#include "scsiTape.h"
#include "scsiDevice.h"
#include "stdlib.h"
#include "fs.h"
#include "exabyteTape.h"
#include "string.h"
/*
* The Exabyte drives have 1K blocks.
*/
#define EXABYTE_BLOCK_SIZE 1024
/*
* Sense data returned from the Exabyte tape controller.
*/
#define EXABYTE_SENSE_BYTES 26
typedef struct {
ScsiClass7Sense extSense; /* 8 Bytes */
unsigned char pad8; /* Reserved */
unsigned char pad; /* Reserved */
unsigned char pad10; /* Reserved */
unsigned char pad11; /* Reserved */
/*
* SCSI 2 support.
*/
unsigned char senseCode; /* 0x4 if sense key is NOT_READY */
unsigned char senseCodeQualifier; /* 00 - volume not mounted.
* 01 - rewinding or loading */
unsigned char pad14; /* Reserved */
unsigned char pad15; /* Reserved */
unsigned char highErrorCnt; /* High byte of error count */
unsigned char midErrorCnt; /* Middle byte of error count */
unsigned char lowErrorCnt; /* Low byte of error count */
/*
* Error bits that are command dependent. 0 is ok, 1 means error.
* These are defined on pages 37-38 of the User Manual, Rev.03
*/
#if BYTE_ORDER == BIG_ENDIAN
unsigned char PF :1; /* Power failure */
unsigned char BPE :1; /* SCSI Bus Parity Error */
unsigned char FPE :1; /* Formatted buffer parity error */
unsigned char ME :1; /* Media error */
unsigned char ECO :1; /* Error counter overflow */
unsigned char TME :1; /* Tape motion error */
unsigned char TNP :1; /* Tape not present */
unsigned char BOT :1; /* Set when tape is at BOT */
unsigned char XFR :1; /* Transfer Abort Error */
unsigned char TMD :1; /* Tape Mark Detect Error */
unsigned char WP :1; /* Write Protect */
unsigned char FMKE :1; /* File Mark Error */
unsigned char URE :1; /* Data flow underrun. Media error. */
unsigned char WE1 :1; /* Max write retries attempted */
unsigned char SSE :1; /* Servo System error. Catastrophic */
unsigned char FE :1; /* Formatter error. Catastrophic */
unsigned char pad21 :6; /* Reserved */
unsigned char WSEB :1; /* Write Splice Error, hit blank tape */
unsigned char WSEO :1; /* Write Splice Error, overshoot */
#else /* BYTE_ORDER == LITTLE_ENDIAN */
unsigned char BOT :1; /* Set when tape is at BOT */
unsigned char TNP :1; /* Tape not present */
unsigned char TME :1; /* Tape motion error */
unsigned char ECO :1; /* Error counter overflow */
unsigned char ME :1; /* Media error */
unsigned char FPE :1; /* Formatted buffer parity error */
unsigned char BPE :1; /* SCSI Bus Parity Error */
unsigned char PF :1; /* Power failure */
unsigned char FE :1; /* Formatter error. Catastrophic */
unsigned char SSE :1; /* Servo System error. Catastrophic */
unsigned char WE1 :1; /* Max write retries attempted */
unsigned char URE :1; /* Data flow underrun. Media error. */
unsigned char FMKE :1; /* File Mark Error */
unsigned char WP :1; /* Write Protect */
unsigned char TMD :1; /* Tape Mark Detect Error */
unsigned char XFR :1; /* Transfer Abort Error */
unsigned char WSEO :1; /* Write Splice Error, overshoot */
unsigned char WSEB :1; /* Write Splice Error, hit blank tape */
unsigned char pad21 :6; /* Reserved */
#endif /* BYTE_ORDER */
unsigned char pad22; /* Reserved */
unsigned char highRemainingTape; /* High byte of remaining tape len */
unsigned char midRemainingTape; /* Middle byte of remaining tape len */
unsigned char lowRemainingTape; /* Low byte of remaining tape len */
} ExabyteSense; /* Known to be 26 Bytes big (for
* Drives made in/after 1988) */
/*
* Definitions for the mode select command. The MODE_SELECT data
* consists of a 4 byte header, zero or one 8 byte block descriptors,
* and finally from zero to 4 bytes of Vendor Unique Parameters.
* For simplicity we'll always send 1 block descriptor and 4 parameter bytes.
*/
typedef struct ExabyteModeSelBlock {
unsigned char density; /* Density code == 0. Only one dens. */
unsigned char highCount; /* == 0 */
unsigned char midCount; /* == 0 */
unsigned char lowCount; /* == 0 */
unsigned char pad1; /* Reserved */
unsigned char highLength; /* Length of the blocks on tape */
unsigned char midLength; /* 0 means variable length */
unsigned char lowLength; /* Default is 1024 bytes */
} ExabyteModeSelBlock; /* 8 Bytes */
typedef struct ExabyteModeSelParams {
ScsiTapeModeSelectHdr header;
ExabyteModeSelBlock block;
#if BYTE_ORDER == BIG_ENDIAN
unsigned char cartidgeType :1; /* 1 == p5 European.
* 0 == P6 Domestic */
unsigned char :3; /* Reserved */
unsigned char noBusyEnable :1; /* 0 == Report Busy Status (default)
* 1 == No Busy Enable, cmd queued */
unsigned char evenByteDscnct :1; /* 0 == Even or Odd byte disconnect
* 1 == Even Byte disconnect */
unsigned char parityEnable :1; /* 0 == Parity disabled (default) */
unsigned char noAutoLoad :1; /* 0 == Auto load enabled (default) */
#else /* BYTE_ORDER == LITTLE_ENDIAN */
unsigned char noAutoLoad :1; /* 0 == Auto load enabled (default) */
unsigned char parityEnable :1; /* 0 == Parity disabled (default) */
unsigned char evenByteDscnct :1; /* 0 == Even or Odd byte disconnect
* 1 == Even Byte disconnect */
unsigned char noBusyEnable :1; /* 0 == Report Busy Status (default)
* 1 == No Busy Enable, cmd queued */
unsigned char :3; /* Reserved */
unsigned char cartidgeType :1; /* 1 == p5 European.
* 0 == P6 Domestic */
#endif /* BYTE_ORDER */
unsigned char pad1; /* RESERVED */
/*
* The Motion threashold must exceed the Reconnect threshold.
* Values represent 1K byte increments.
* Motion - default 0xF0, valid range 0x01 -> 0xF7
* Reconnect - default 0x40, valid range 0x01 to 0xF7
* WRITE - lower motion threshold for faster transfer.
* READ - raise reconnect threshold for faster transfer.
* Basically these control the amount of data kept in the buffer
* and hence the latency.
*/
unsigned char motion; /* Defines how many Kbytes are buffered
* before writing to the tape begins,
* or when reconnecting on a read */
unsigned char reconnect; /* Defines how many Kbytes are left
* in the buffer when the drive
* begins filling it again, either
* by reading the tape or reconnecting
* and getting more data from the
* SCSI bus. */
} ModeSelParams;
static ReturnStatus ExabyteError _ARGS_((ScsiTape *tapePtr,
unsigned int statusByte, int senseLength, char *senseDataPtr));
/*
*----------------------------------------------------------------------
*
* DevExabyteAttach --
*
* Initialize the DevSCSITape state for a Exabyte drive.
*
* Results:
* None.
*
* Side effects:
* Sets the type and call-back procedures.
*
*----------------------------------------------------------------------
*/
/*ARGSUSED*/
ReturnStatus
DevExabyteAttach(devicePtr, devPtr, tapePtr)
Fs_Device *devicePtr; /* Fs_Device being attached. */
ScsiDevice *devPtr; /* SCSI device handle for drive. */
ScsiTape *tapePtr; /* Tape drive state to be filled in. */
{
ScsiInquiryData *inquiryPtr;
/*
* First we must verify that the attached device is a Exabyte. We do
* that by examinging the Inquiry data in the ScsiDevice handle. The
* lack of Inquiry data would imply its not a Exabyte.
*/
inquiryPtr = (ScsiInquiryData *) (devPtr->inquiryDataPtr);
if ( (devPtr->inquiryLength < sizeof(ScsiInquiryData)) ||
(strncmp((char *) (inquiryPtr->vendorID), "EXABYTE ",8) != 0) ) {
return DEV_NO_DEVICE;
}
/*
* The exabyte has a different BLOCK and we liked to check the
* vendor unique bits on error.
*/
tapePtr->blockSize = EXABYTE_BLOCK_SIZE;
tapePtr->errorProc = ExabyteError;
if (!(strncmp((char *)(inquiryPtr->productID), "EXB-8200",8))) {
tapePtr->name = "Exabyte 8200";
} else if (!(strncmp((char *)(inquiryPtr->productID), "EXB-8500",8))) {
tapePtr->name = "Exabyte 8500";
} else {
tapePtr->name = "Exabyte UNKNOWN";
}
return SUCCESS;
}
/*
*----------------------------------------------------------------------
*
* ExabyteError --
*
* Handle error conditions from a Exabyte based tape drive.
*
* Results:
* An error code.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static ReturnStatus
ExabyteError(tapePtr, statusByte, senseLength, senseDataPtr)
ScsiTape *tapePtr; /* SCSI Tape that's complaining. */
unsigned int statusByte; /* The status byte of the command. */
int senseLength; /* Length of SCSI sense data in bytes. */
char *senseDataPtr; /* Sense data. */
{
ReturnStatus status;
register volatile ExabyteSense *exabyteSensePtr =
(volatile ExabyteSense *)senseDataPtr;
status = DevSCSITapeError(tapePtr, statusByte, senseLength, senseDataPtr);
if (status == SUCCESS) {
return status;
}
if (exabyteSensePtr->extSense.badBlockLen) {
printf("Exabyte Block Length Mismatch\n");
status = DEV_HARD_ERROR;
}
if (exabyteSensePtr->TMD) {
printf("Warning: Exabyte Tape Mark Detect error\n");
status = DEV_HARD_ERROR;
}
if (exabyteSensePtr->XFR) {
printf("Warning: Exabyte Transfer abort error\n");
status = DEV_HARD_ERROR;
}
if (exabyteSensePtr->PF) {
/* Media changed or after power up */
}
if (exabyteSensePtr->BPE) {
printf("Warning: Exabyte SCSI Bus Parity error\n");
}
if (exabyteSensePtr->FPE) {
printf("Warning: Exabyte Formatter Parity error\n");
}
if (exabyteSensePtr->ME) {
/* Media Error already reported via sense key */
}
if (exabyteSensePtr->ECO) {
printf("Warning: Exabyte error counter overflow\n");
}
if (exabyteSensePtr->TME) {
printf("Warning: Exabyte Tape Motion error\n");
}
if (exabyteSensePtr->TNP) {
printf("Warning: Exabyte tape not present\n");
}
if (exabyteSensePtr->BOT) {
/* At the beginning of tape */
}
if (exabyteSensePtr->FMKE) {
printf("Exabyte File Mark Error\n");
}
if (exabyteSensePtr->URE) {
printf("Warning: Exabyte Data Flow Underrun\n");
}
if (exabyteSensePtr->WE1) {
printf("Warning: Exabyte maximum write retries attempted\n");
}
if (exabyteSensePtr->SSE) {
printf("Warning: Exabyte Servo System error, catastrophic failure!\n");
}
if (exabyteSensePtr->FE) {
printf("Warning: Exabyte Formatter error, catastrophic failure!\n");
}
return(status);
}